/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.buzzwords.resources;

import com.buzzwords.clientside.domain.ErrorField;
import com.buzzwords.clientside.domain.Field;
import com.buzzwords.clientside.domain.Result;
import com.buzzwords.dataaccess.Database;
import com.buzzwords.exceptions.DuplicateEntryException;
import com.buzzwords.factories.BuzzwordDatabaseFactory;
import com.buzzwords.factories.DatabaseFactory;
import com.buzzwords.factories.EmailFactory;
import com.buzzwords.domain.User;
import com.buzzwords.utils.MailClient;
import com.buzzwords.utils.RandomPassword;
import com.sun.jersey.api.view.Viewable;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import net.sf.json.JSONObject;

/**
 *
 * @author potlow
 */
@Path("/users")
public class UsersResource {

    /**
     * Resource for add accounts for users. Special case test@test.com with password d19a0a6f9db646a2a762.
     * Gets UUID d19a0a6f-9db6-46a2-a762-d71873e400bb
     * @param email email of user
     * @param password password of user
     * @return Result object containing success and details
     */
    @Path("/add/")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    public String addUser(@FormParam("signUpEmail") @DefaultValue("") String email, @FormParam("signUpPassword") @DefaultValue("") String password) {
        Boolean testUser = false;
        Result result = new Result();

        // check to see if email is valid email
        if (email.isEmpty() || !email.matches(".+@.+\\.[a-z]+")) {
            result.setSuccess(false);
            ErrorField error = new ErrorField("signUpEmailTextField", "This field should be an email in the format \"user@domain.com\"");
            result.getErrors().add(error);
            return JSONObject.fromObject(result).toString();
        }

        // check to see if password is valid length
        if (password.length() < 8 || password.length() > 20) {
            result.setSuccess(false);
            ErrorField error = new ErrorField("signUpPasswordTextField", "Passwords must be between 8 and 20 characters long");
            result.getErrors().add(error);
            return JSONObject.fromObject(result).toString();
        }

        // Create user from paramters received
        User user = new User(email, password);
        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database database = databaseFactory.getDatabase("User Email");

        // if special case test user, assign specific uuid
        if (user.getEmail().equals("test@test.com") && user.getPassword().equals("d19a0a6f9db646a2a762")) {
            user.setUuid("d19a0a6f-9db6-46a2-a762-d71873e400bb");
            testUser = true;
        }

        // check to see if test.com is the domain
        if (!testUser) {
            int index = email.indexOf("@");
            if (email.substring(index+1).equals("test.com")) {
                result.setSuccess(false);
                ErrorField error = new ErrorField("signUpEmailTextField", "test.com is an invalid domain");
                result.getErrors().add(error);
                return JSONObject.fromObject(result).toString();
            }
        }

        try {

            // Assign signed up notification to new user
            //Notification notification = new Notification("Sign Up", "Check out the quickstart guide", user);
            //user.getNotifications().add(notification);
            database.performCreate(user);

            // Insert new user in db and mark result as success
            result.setSuccess(true);

            // send validation email to users email
            if(!testUser) {
                EmailFactory emailFactory = new EmailFactory(user);
                String signUpEmail = emailFactory.getEmail("Sign Up");
                new MailClient(user.getEmail(), "Thanks for joining", signUpEmail).start();
            }
        } catch (DuplicateEntryException dee) {

            // if user's email already found in db, mark result as failed and return with error detail
            result.setSuccess(false);
            ErrorField signUpEmailTextField = new ErrorField("signUpEmailTextField", dee.getFriendlyMessage());
            result.getErrors().add(signUpEmailTextField);
        }

        // return success result
        return JSONObject.fromObject(result).toString();
    }

    @Path("/validate/{uuid}")
    @GET
    public Response validateUser(@PathParam("uuid") String uuid) {
        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database database = databaseFactory.getDatabase("User Uuid");

        List<Object> users = database.performRead(uuid);
        if (users.isEmpty()) {
            Result result = new Result(false);
            return Response.ok(new Viewable("/registered.jsp", result)).build();
        }

        User user = (User) users.get(0);
        user.setValidated(true);
        database.performUpdate(user);
        return Response.ok(new Viewable("/registered.jsp", user)).build();
    }

    @Path("/reset/password/")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    public String resetPassword(@FormParam("email") String email) {
        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database database = databaseFactory.getDatabase("User Email");

        List<Object> users = database.performRead(email);
        if (users.isEmpty()) {
            Result result = new Result(false);
            return JSONObject.fromObject(result).toString();
        }

        User user = (User) users.get(0);
        user.setPassword(RandomPassword.getRandomString(10));
        database.performUpdate(user);

        EmailFactory emailFactory = new EmailFactory(user);
        String passwordResetEmail = emailFactory.getEmail("Forgot Password");
        new MailClient(user.getEmail(), "Buzzwords Password Reset", passwordResetEmail).start();

        return JSONObject.fromObject(new Result(true)).toString();
    }

    @Path("/login/")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    public String login(@FormParam("email") String email, @FormParam("password") String password) {
        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database database = databaseFactory.getDatabase("User Email");

        List<Object> users = database.performRead(email);
        if (users.isEmpty()) {
            Result result = new Result(false);
            return JSONObject.fromObject(result).toString();
        }

        User user = (User) users.get(0);
        if (user.getPassword().equals(password)) {
            if (!user.isValidated()) {
                return JSONObject.fromObject(new Result(false)).toString();
            }
            Result result = new Result(true);
            return JSONObject.fromObject(result).toString();
        }

        return JSONObject.fromObject(new Result(false)).toString();
    }
}
